function SmoothRoll ( table_id )
{
	this._container = document.getElementById ( table_id );
	this._items = [];

	this._start = 0;
	this._rows_to_show = 0;
	this._stopped = true;
	this._scrollable = true;

	this.min_row_height = 10;
	this.scroll_speed = 1;
	this.scroll_time = 100;

	this.clear = function ()
	{
		if ( this._interval ) clearInterval ( this._interval );

		this._stopped = true;
		this._scrollable = true;
		this._start = 0;
		this._rows_to_show = 0;
		this._interval = null;

		this._items = [];
	};

	this.init = function ()
	{
		this._start = 0;
		this._len = this._items.length;

		this._first_render ();
	};

	this.add_item = function ( txt )
	{
		this._items.push ( txt );
	};

	this.start = function ()
	{
		var _obj = this;

		if ( ! this._stopped ) return;

		this._stopped = false;
		this._interval = setInterval ( function () { _obj.scroll ( - _obj.scroll_speed ); }, this.scroll_time );
	};

	this.stop = function ()
	{
		if ( this._interval ) clearInterval ( this._interval );
		this._stopped = true;
	};

	this._first_render = function ()
	{
		var t, i;
		var tr, td, row, el;
		var _obj = this;

		this._table = document.createElement ( 'table' );
		//this._table.style.position = "relative";
		this._table.style.display = "inline-block";
		this._table.style.top = "0";
		this._table.style.left = "0";
		this._table_body = document.createElement ( 'tbody' );

		this._table.appendChild ( this._table_body );
		this._container.appendChild ( this._table );

		this._rows_to_show = 0;

		this._table.onmouseover = function () { _obj.stop (); };
		this._table.onmouseout  = function () { _obj.start (); };
		this._table.style.width = this._container.clientWidth + "px";

		while ( ( this._table.clientHeight - this.min_row_height ) < this._container.clientHeight  )
		{
			el = this._rows_to_show ++;
			if ( el >= this._len ) break;
			
			row = this._items [ el ];

			tr = document.createElement ( 'tr' );
			td = document.createElement ( 'td' );
			tr.appendChild ( td );

			td.innerHTML = row;

			this._table_body.appendChild ( tr );

			this._start ++;
			//console.debug ( this._table.clientHeight );
		}

		if ( this._rows_to_show > this._len ) this._scrollable = false;

		this._rows_to_show -= 1;
		this._table_pos = 0;

		this._calc_row_height ();
	};

	this._calc_row_height = function ()
	{
		this._row_height = this._table_body.firstChild.clientHeight;
	};

	this.scroll = function ( delta )
	{
		if ( ! this._scrollable ) return;

		this._table_pos += delta;

		// FIXME: forse c'e' da controllare in modo differente per
		// gli offset superiori e quelli inferiori
		if ( Math.abs ( this._table_pos ) > ( this._row_height + Math.abs ( delta )  ) )
		{
			this._model_scroll_up ();
		}

		this._table.style.marginTop = this._table_pos + "px";
	};

	this._model_scroll_up = function ()
	{
		var t, data_row;
		var pos;
		// Rimuovo la prima riga
		var row = this._table_body.firstChild;

		if ( ! row || ! row.firstChild ) return;

		// Mi sposto con l'offset di visualizzazione di un elemento
		pos = this._start = ( this._start + 1 ) % this._len;

		// prendo la prossima row
		data_row = this._items [ pos ];

		row.firstChild.innerHTML = data_row;

		this._table_body.removeChild ( row );
		this._table.style.marginTop = "0px";
		this._table_body.appendChild ( row );
		this._table_pos = 0;
		this._calc_row_height ();

		// console.debug ( "SCROLL" );
	};
}
